package com.example.his.api.schedule;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.his.api.db.dao.FlowRegulationDao;
import com.example.his.api.exception.HisException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;

@Component
@Slf4j
public class FlowRegulationSchedule {
  @Resource
  private FlowRegulationDao flowRegulationDao;
  
  @Resource
  private RedisTemplate redisTemplate;
  
  //  每天7-16点之间，每分钟计算一次推荐的科室列表
  
  //  @Scheduled(cron = "0,20,40 * * * * ?")  // 每20秒执行一次
  @Scheduled(cron = "0 * 7-16 * * ?") // 7-16点每分钟执行一次
  @Transactional
  public void refreshFlowRegulation() {
    //    查询所有的调流科室
    ArrayList <HashMap> placeList = flowRegulationDao.searchAllPlace();
    //    便利所有的体检调流科室
    placeList.forEach(item -> {
      int id = Integer.parseInt(item.get("id").toString());
      String place = item.get("place").toString();
      //      获取所有体检人的排队缓存
      Set <String> keys = redisTemplate.keys("flow_regulation_customer#");
      int sum = 0;
      for(String key: keys) {
        ValueOperations ops = redisTemplate.opsForValue();
        int placeId = Integer.parseInt(ops.get(key).toString());
        if(placeId == id) {
          sum++;
        }
      }
      
      HashMap param = new HashMap();
      param.put("id", id);
      param.put("realNum", sum);
      
      int i = flowRegulationDao.updateRealNum(param);
      if(i != 1) {
        throw new HisException("更新体检调流排队人数失败");
      }
    });
    
    //    查询当前的模式
    String value = redisTemplate.opsForValue().get("setting#auto_flow_regulation").toString();
    boolean mode = Boolean.parseBoolean(value);
    ArrayList list = new ArrayList();
    if(mode) {
      //   自动限流模式推荐科室排名
      list = flowRegulationDao.searchRecommendWithWeight();
    } else {
      //   手动限流模式推荐科室排名
      list = flowRegulationDao.searchRecommendWithPriority();
    }
    
    ArrayList res = new ArrayList();
    list.forEach(item -> {
      JSONObject json = JSONUtil.parseObj(item);
      res.add(json.toString());
    });
    
    redisTemplate.executePipelined(new SessionCallback <Object>() {
      @Override
      public Object execute(RedisOperations operations) throws DataAccessException {
        operations.delete("flow_regulation");
        operations.opsForList().rightPushAll("flow_regulation", res);
        return null;
      }
    });
    System.out.println("刷新排号推荐科室列表成功");
    log.debug("刷新排号推荐科室列表成功");
    
  }
}
